package com.game.battle.common.math;

public class Box2 {
	/// <summary>
	/// Box center
	/// </summary>
	public Vector2 center;

	/// <summary>
	/// First box axis. Must be unit length!
	/// </summary>
	public Vector2 axis0;

	/// <summary>
	/// Second box axis. Must be unit length!
	/// </summary>
	public Vector2 axis1;

	/// <summary>
	/// Extents (half sizes) along Axis0 and Axis1. Must be non-negative!
	/// </summary>
	public Vector2 extents;


	/// <summary>
	/// Creates new Box2 instance.
	/// </summary>
	/// <param name="center">Box center</param>
	/// <param name="axis0">First box axis. Must be unit length!</param>
	/// <param name="axis1">Second box axis. Must be unit length!</param>
	/// <param name="extents">Extents (half sizes) along Axis0 and Axis1. Must be non-negative!</param>
	public Box2(Vector2 center, Vector2 axis0, Vector2 axis1, Vector2 extents)
	{
		this.center = center;
		this.axis0 = axis0;
		this.axis1 = axis1;
		this.extents = extents;
	}

	/// <summary>
	/// Creates Box2 from AxisAlignedBox2
	/// </summary>
	//TODO
//	public Box2(AAB2 box)
//	{
//		box.CalcCenterExtents(out Center, out Extents);
//		Axis0 = Vector2ex.UnitX;
//		Axis1 = Vector2ex.UnitY;
//	}

	public Box2() {
		this.center = Vector2.zero;
		this.axis0 = Vector2.zero;
		this.axis1 = Vector2.zero;
		this.extents = Vector2.zero;
	}

	/// <summary>
	/// Returns axis by index (0, 1)
	/// </summary>
	public Vector2 getAxis(int index)
	{
		if (index == 0) return axis0;
		if (index == 1) return axis1;
		return Vector2.zero;
	}


	/// <summary>
	/// Calculates 4 box corners and returns them in an allocated array.
	/// See array-less overload for the description.
	/// </summary>
	public Vector2[] calcVertices()
	{
		Vector2 extAxis0 = Vector2.multi(axis0, extents.x) ;
		Vector2 extAxis1 = Vector2.multi(axis1, extents.y);

		Vector2[] result =
		{
			Vector2.sub( Vector2.sub(this.center, extAxis0), extAxis1),
			Vector2.sub( Vector2.add(this.center, extAxis0), extAxis1),
			Vector2.add( Vector2.add(this.center, extAxis0), extAxis1),
			Vector2.add( Vector2.sub(this.center, extAxis0), extAxis1),
		};
		return result;
	}

	/// <summary>
	/// Calculates 4 box corners and fills the input array with them (array length must be 4).
	/// See array-less overload for the description.
	/// </summary>
	public void calcVertices(Vector2[] array)
	{
		Vector2 extAxis0 = Vector2.multi(axis0, extents.x);
		Vector2 extAxis1 = Vector2.multi(axis1, extents.y);

		array[0] = Vector2.sub( Vector2.sub(this.center, extAxis0), extAxis1);
		array[1] = Vector2.sub( Vector2.add(this.center, extAxis0), extAxis1);
		array[2] = Vector2.add( Vector2.add(this.center, extAxis0), extAxis1);
		array[3] = Vector2.add( Vector2.sub(this.center, extAxis0), extAxis1);
	}

	/// <summary>
	/// Returns area of the box as Extents.x * Extents.y * 4
	/// </summary>
	public float calcArea()
	{
		return 4f * extents.x * extents.y;
	}


	/// <summary>
	/// Tests whether a point is contained by the box
	/// </summary>
	public boolean contains(Vector2 point)
	{
		Vector2 diff = new Vector2();
		diff.x = point.x - center.x;
		diff.y = point.y - center.y;
		float proj;
		proj = diff.dot(axis0);
		if (proj < -extents.x) return false;
		if (proj > extents.x) return false;
		proj = diff.dot(axis1);
		if (proj < -extents.y) return false;
		if (proj > extents.y) return false;
		return true;
	}

}
